/*
 *===========================================================================
 *
 *          Name: util.c
 *        Create: Fri 01 Jun 2012 06:44:56 PM CST
 *
 *   Discription: some usefull functions
 *       Version: 1.0.0
 *
 *        Author: yuwei.zhang
 *         Email: yuwei.zhang@besovideo.com
 *
 *===========================================================================
 */

#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netdb.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>

#include "jkglobal.h"
#include "jkutils.h"

int _parse_data(unsigned char *data, char *string)
{
    char p[128];
    char *str;
    char *token;
    int  i = 0;
    int val = 0;

    strncpy(p, string, strlen(string));

    for (str = p;;str = NULL)
    {
        token = strtok(str, ",");
        if (token == NULL) {
            break;
        } else {
            sscanf(token, "%02x", &val);
            data[i++] = val;
        }
    }
    
    return i+1;
}

int _parse_data_string(char data[][MAX_EACH_DATA_STRING], char *string, int maxlen, const char sign)
{
    char     tmpstr[2048];
    int      i = 0, j = 0;
    int      indx = 0;


    memset(tmpstr, 0, sizeof(tmpstr));
    strncpy(tmpstr, string, strlen(string));
    
    for (i = 0; i < maxlen; i++) {
        memset(data[i], 0, sizeof(data[i]));
        for (j = 0; ;j++) {
            if (tmpstr[indx] != sign && tmpstr[indx] != '\0') {
                data[i][j] = tmpstr[indx];
                indx++;
            } else {
                indx++; break;
            }   
        }   
    }   

    return i+1;
}

int _parse_data_string2(char *string, char *save, int arrsize, int maxlen, const char sign)
{
    if (string == NULL || save == NULL || arrsize < 0 || maxlen < 0) return -1;
    int      i = 0, j = 0;
    int      counts = 0;
    char    *pos = index(string, sign);
    while((pos = index(pos, sign))) {
        pos++;
        counts++;
    };
    counts += 1;   // we find counts

    pos = string;
    memset(save, 0, arrsize*maxlen);
    for (i = 0; i < maxlen; i++) {
        if (i >= counts) break;    // only deal we find counts
        char *p = save+i*(arrsize);
        for (j = 0; j < arrsize;j++) {
            if (j == arrsize-1 || *pos == sign || *pos == '\0') { 
                *(p+j) = '\0'; 
                if ((pos = index(pos, sign))) pos++;
                break;
            }
            *(p+j) = *pos++;
        }   
    }
    return i;    // return what we realy deal, maybe not maxlen
}


int _parse_data_char(unsigned char *data, char *string, int maxlen, const char *sign)
{
    char p[128];
    char *str;
    char *token;
    int  i = 0;
    char val;

    strncpy(p, string, strlen(string));

    for (str = p;;str = NULL)
    {
        if (i >= maxlen) break;
        token = strtok(str, sign);
        if (token == NULL) {
            break;
        } else {
            sscanf(token, "%c", &val);
            data[i++] = val;
        }
    }
    
    return i+1;
}

int _parse_string_int(char *string, int *save, int maxlen, const char *sign)
{
    char  p[128];
    char *str;
    char *token;
    int   i = 0;
    int   val = 0;

    strncpy(p, string, strlen(string));

    for (str = p;;str = NULL)
    {
        if (i >= maxlen) break;
        token = strtok(str, sign);
        if (token == NULL) {
            break;
        } else {
            sscanf(token, "%d", &val);
            save[i++] = val;
        }
    }
    
    return i+1;
}

int clear_parenthesis(char *save, char *string)
{
    if (save == NULL || string == NULL) return -1;

    int    len = strlen(string);
    if (string[0] != '(' && string[len-1] != ')') return -2;

    int    i = 0;
    int    j = 1;
    if (string[0] != '(') j = 0;
    for (i = 0; i < len; i++) {
        if (string[i] == ')') break;
        save[i] = string[j++];
    }

    return 0;
}

#define h_addr h_addr_list[0]
char *GetIp(char *dn_or_ip, const char *eth)
{
   struct hostent *host;
   struct ifreq req;
   int sock;
   if (dn_or_ip == NULL) return NULL;
   if (strcmp(dn_or_ip, "localhost") == 0) 
   {
	  sock = socket(AF_INET, SOCK_DGRAM, 0);
	  strncpy(req.ifr_name, eth, IFNAMSIZ);
	  if ( ioctl(sock, SIOCGIFADDR, &req) < 0 ) 
	  {
		 JKERR("ioctl error: %s\n", strerror (errno));
		 return NULL;
	  }
	  dn_or_ip = (char *)inet_ntoa(*(struct in_addr *) &((struct sockaddr_in *) &req.ifr_addr)->sin_addr);
	  shutdown(sock, 2);
	  close(sock);
   } 
   else 
   {
	  host = gethostbyname(dn_or_ip);
	  if (host == NULL) 
	  {
		 return NULL;
	  }
	  dn_or_ip = (char *)inet_ntoa(*(struct in_addr *)(host->h_addr));
   }
   return dn_or_ip;
}


int resize_data(char **data, int protobuflen, char* protobufdata)
{
    if (protobufdata == NULL) return -1;
    static int needlen = 0;
    static int pos = 0;

    if (*data == NULL) {
        needlen = protobuflen;
        pos = 0;
        *data = (char*)malloc(needlen*sizeof(char*)+1);
    }else {
        needlen += protobuflen;
        *data = (char*)realloc(*data, needlen*sizeof(char*)+1);
    }
    if (*data == NULL) {
        return -2;
    }
    memcpy(*data+pos, protobufdata, protobuflen);
    pos += protobuflen;

    return pos; 
}

#define MC_MOUNTED_FILE          "/proc/mounts"
int MC_is_mounted(char *device)
{
    if (device  == NULL) return -1;
    int  ret = 0;

    FILE *fd = fopen(MC_MOUNTED_FILE, "r");
    if (fd == NULL) {
        JKERR("open [%s] ERROR\n", MC_MOUNTED_FILE);
        return -2;
    }
    int   i;
    char  dev[512];
    memset(dev, 0, sizeof(dev));
    // read most 16 lines, find if has "device"
    // if has, device is mounted, return 1
    for (i = 0; i < 16; i++) {
        // just need read 16 chars
        if (fgets(dev, 512, fd) != NULL) {
            if (strcasestr(dev, device)) {  // when find ,exit
                ret = 1;
            }
        }
    }
    if (fd) { fclose(fd); fd = NULL; }

    return ret;
}

int MC_RemoveLastBreak(char *args)
{
    if (args == NULL) return -1;

    int  len = strlen(args);
    if (args[len-1] == '\n') 
        args[len-1] = '\0';

    return 0;
}

int MC_getflow(const char *interface, unsigned long long *recv,unsigned long long *send, unsigned long long *total)
{
    int ret = 0;
    unsigned int l1,l2;
    FILE *fp = fopen("/proc/net/dev","r");
    if(!fp) {
        perror("fail to open /proc/net/dev");
        if(recv)  *recv  = 0; 
        if(send)  *send  = 0; 
        if(total) *total = 0; 
        return -1; 
    }   
    char buf[512];
    while(fgets(buf,512,fp)) {
        if(strstr(buf,interface)) {
            char *ptr;
            if((ptr = strchr(buf, ':')) == NULL) {
                ret = -1; 
                goto out;
            }   
            sscanf(++ptr,"%d",&l1);
            sscanf(++ptr,"%*d%*d%*d%*d%*d%*d%*d%*d%d",&l2);
            if(recv)  *recv  = l1; 
            if(send)  *send  = l2; 
            if(total) *total = l1 + l2; 
            goto out;
        }   
    }   
out:
    if (fp) { fclose(fp); fp = NULL; }
    return ret;
}



/*=============== End of file: util.c ==========================*/

